/************************************************************************
 * @file PluginFactory.cpp
 * @author Ian Chen
 * @version 1.0
 *
 * @section LICENSE
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
 * General Public License for more details at
 * http://www.gnu.org/licenses/lgpl.html
 *
 ************************************************************************/
#include <QObject>

#include <plugin/plugin/PluginFactory.h>

#include <plugin/plugin/AbstractPlugin.h>
#include <plugin/service/ServiceRegistry.h>

namespace antu
{
namespace plugin
{

PluginFactory::PluginFactory()
{
}

PluginFactory::~PluginFactory()
{
    this->m_oPluginInfos.clear();
}

bool PluginFactory::registerPluginInfo(const QString &pluginCode, pPluginInstantiationFunc pInstantiationFunc)
{
    if (pInstantiationFunc == nullptr)
        return false;

    if (this->m_oPluginInfos.find(pluginCode) == this->m_oPluginInfos.end())
    {
        this->m_oPluginInfos.insert(pair<QString,  pPluginInstantiationFunc>(pluginCode, pInstantiationFunc));
        return true;
    }
    return false;
}

AbstractPlugin *PluginFactory::createPlugin(const QString& pluginCode,
                                            PluginDescriptionSharedPtr& description,
                                            ServiceRegistry* pRegistry,
                                            QObject* pParent)
{
    map<QString, pPluginInstantiationFunc>::iterator iter = this->m_oPluginInfos.find(pluginCode);

    if (iter != this->m_oPluginInfos.end())
    {
        pPluginInstantiationFunc pInstantiationFunc = iter->second;
        AbstractPlugin* pPlugin = (*pInstantiationFunc)(description, pRegistry);

        if (pPlugin != nullptr && pParent != nullptr)
            pPlugin->setParent(pParent);
        return pPlugin;
    }
    else
    {
        return nullptr;
    }
}

PluginFactory PluginFactory::Factory;
}
}
